/*
 * Simulator Server.
 * <p>
 * 模拟服务端程序.<br/>
 * 用于没有前后端分离开发过程中的业务模拟.
 * </p>
 * @author wangds<wangds2016@163.com>
 * @modified 2017-10-14
 */


var http = require('http');
var url = require('url');
var fs = require('fs');
var path = require('path');

//应答mine-type列表.
var MINE_MAP = {
    "css": "text/css",
    "gif": "image/gif",
    "html": "text/html",
    "ico": "image/x-icon",
    "jpeg": "image/jpeg",
    "jpg": "image/jpeg",
    "js": "text/javascript",
    "json": "application/json",
    "pdf": "application/pdf",
    "png": "image/png",
    "svg": "image/svg+xml",
    "swf": "application/x-shockwave-flash",
    "tiff": "image/tiff",
    "txt": "text/plain",
    "wav": "audio/x-wav",
    "wma": "audio/x-ms-wma",
    "wmv": "video/x-ms-wmv",
    "xml": "text/xml"
  };

  /*
   * 默认端口.
   */
  var PORT = 1840;

  //获得命令行参数
  var args = process.argv.splice(2);
 
  //目前只处理"-p"参数，用于指定端口.
  //兼容"-p{port}"和"-p {port}"两种方式.
  args.forEach(function(val, idx){
      if(val&&val.startsWith('-p')){
          if(val.length>2){
              //处理"-p{port}"形式的参数.
              PORT = Number.parseInt(val.substr(2));
          }else{
              //处理"-p {port}"形式的参数.
              var port = args[idx+1];
              console.log("port : "+port)
              console.log(port.indexOf('-')!=0)
              console.log(Number.isInteger(port))
              if(port&&port.indexOf('-')!=0){
                  try{
                    PORT = Number.parseInt(port);
                  }catch(e){
                      console.error(e);
                  }
              }
          }
      }
  });

  

console.log('This server\'s port is ' + PORT + '.');

//创建服务对象.
var server = http.createServer(
    function(req, resp){
        //获得请求路径中与文件路径重合的部分.
        //即不包含端口后第一个目录的路径.
        //例如:
        //  http://localhost:1840/app/data/test, 有效路径是"/data/test".
        var path = url.parse(req.url).pathname;
        var idx = path.indexOf('/', 1);
        var sub_path = path.substr(idx);
        
        //处理文件扩展名，以及应答的mine-type.
        var ext = 'json'; //文件扩展名默认为"json".
        var ext_idx = path.lastIndexOf('\.');
        if(ext_idx>=0){
            ext = path.substr(ext_idx+1);
        }else{
            //请求路径中没有扩展名的时候给有效路径添加默认扩展名.
            //生产环境中的请求一般情况下都是没有扩展名的，
            //例如:
            // http://server:port/app/biz/listAll,
            //在前端开发的时候，为了减少对后端的依赖，以及开发方便，
            //上述例子中的模拟应答会放在.json文件中，因此在访问
            //模拟数据文件时，需要补全扩展名.
            sub_path += '.json';
        }
        //应答mine-type
        var resp_mine = MINE_MAP[ext];

        //指定应答内容文件在本地"./data"目录下.
        var resp_file_path = './data'+sub_path;

        //处理文件.
        fs.exists(resp_file_path, function(exists){
            if(!exists){
                //文件不存在时的处理.
                console.log('not found the file \'' + resp_file_path + '\'');
                resp.writeHead(404,{
                    'Content-Type':'text/plain'
                });
                resp.write('not found the response.');
                resp.end();
            }else{
                //能够找到文件时的处理.
                fs.readFile(resp_file_path, 'binary', function(err, fileContent){
                    if(err){
                        //文件存在但是读取异常.
                        resp.writeHead(500, {
                            'Content-Type':'text/plain'
                        });
                        resp.end(err);
                    }else{
                        //正常场景.
                        resp.writeHead(200, {
                            'Content-Type':resp_mine,
                            'Access-Control-Allow-Origin':'*',
                            'Access-Control-Allow-Methods':'GET,HEAD,POST,OPTIONS,PUT,DELETE,TRACE,CONNECT',
                            'Access-Control-Max-Age': '36000',
                            'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With',
                        });
                        resp.write(fileContent, 'binary');
                        resp.end();
                        console.log('response finished at '+new Date()+'.');
                    }
                });
            }
        });
    }
);

//监听端口.
server.listen(PORT);

console.log('server is working ... ...');